package com.sky.service.impl;

import com.sky.dto.GoodsSalesDTO;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.*;
import org.apache.poi.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReportServiceImpl implements ReportService {
   @Autowired
   private OrderMapper orderMapper;
   @Autowired
   private UserMapper userMapper;
   @Autowired
   private OrderDetailMapper orderDetailMapper;
    @Override
    public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        dateList.add(end);
        List<Double> list = new ArrayList<>();
        for (LocalDate date : dateList){
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map = new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);
            map.put("status", Orders.COMPLETED);
            Double sumByMap = orderMapper.getSumByMap(map);
            sumByMap = sumByMap == null ? 0.0 :sumByMap;
            list.add(sumByMap);
        }

        return TurnoverReportVO.builder()
                .dateList(StringUtil.join(",",dateList.toArray()))
                .turnoverList(StringUtil.join(",",list.toArray()))
                .build();
    }

    @Override
    public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        dateList.add(end);
        List<Long> newUserList = new ArrayList<>();
        List<Long> totalUserList = new ArrayList<>();
        for (LocalDate date : dateList){
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map = new HashMap();
            map.put("begin",beginTime);
            Long totalUser = userMapper.getUserByCreateTime(map);
            map.put("end",endTime);
            Long newCreateUser = userMapper.getUserByCreateTime(map);
            newUserList.add(newCreateUser);
            totalUserList.add(totalUser);
        }
        return UserReportVO.builder().dateList(StringUtil.join(",",dateList))
                .newUserList(StringUtil.join(",",newUserList))
                .totalUserList(StringUtil.join(",",totalUserList))
                .build();
    }

    @Override
    public OrderReportVO ordersStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = new ArrayList();
        List<Integer> orderCountList = new ArrayList<>();
        List<Integer> validOrderCountList = new ArrayList<>();
        dateList.add(begin);
        while (!begin.equals(end)){
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        dateList.add(end);
        for (LocalDate date : dateList){
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Map map = new HashMap();
            map.put("begin",beginTime);
            map.put("end",endTime);
            Integer countByMap = orderMapper.getCountByMap(map);
            orderCountList.add(countByMap);
            map.put("status", Orders.COMPLETED);
            countByMap = orderMapper.getCountByMap(map);
            countByMap = countByMap == null ? 0 :countByMap;
            validOrderCountList.add(countByMap);
        }

        Double orderCompletionRate = Double.valueOf(validOrderCountList.size() / orderCountList.size());
        Integer totalOrderCount = orderCountList.size();
        Integer validOrderCount = validOrderCountList.size();
        OrderReportVO o = new OrderReportVO();
        o.setOrderCompletionRate(orderCompletionRate);
        o.setOrderCountList(StringUtil.join(",",orderCountList));
        o.setDateList(StringUtil.join(",",dateList));
        o.setTotalOrderCount(totalOrderCount);
        o.setValidOrderCount(validOrderCount);
        o.setValidOrderCountList(StringUtil.join(",",validOrderCountList));
        return o;
    }

    @Override
    public SalesTop10ReportVO top10(LocalDate begin, LocalDate end) {
        LocalDateTime beginTime = LocalDateTime.of(begin, LocalTime.MIN);
        LocalDateTime endTime = LocalDateTime.of(end, LocalTime.MAX);
        List<GoodsSalesDTO> top10Sales = orderDetailMapper.getTop10Sales(beginTime, endTime);

        List<String> nameList = top10Sales.stream()
                .map(GoodsSalesDTO ::getName)
                .collect(Collectors.toList());

        List<Integer> numberList = top10Sales.stream()
                .map(GoodsSalesDTO ::getNumber)
                .collect(Collectors.toList());
        return SalesTop10ReportVO.builder()
                .nameList(StringUtil.join(",",nameList))
                .numberList(StringUtil.join(",",numberList))
                .build();
    }
}
